package cn.legend.travel.attachment.controller.abs;

import cn.legend.travel.attachment.consts.FileConst;
import cn.legend.travel.attachment.vo.UploadResult;
import cn.legend.travel.common.enumerator.ServiceCode;
import cn.legend.travel.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public abstract class FileUpload implements FileConst {
    @Value("${travel.upload.host}")
    private String host;
    @Value("${travel.upload.base-dir-name}")
    private String baseDirName;
    @Value("${travel.upload.root-dir-name}")
    private String uploadRootDirName;
    private String dateDirName;
    private File uploadDir;
    private String fullFileName;
    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/");

    protected UploadResult upload(MultipartFile multipartFile, long maxSize, List<String> validTypes, String fileTypeDirName) throws IOException {
        checkFile(multipartFile, maxSize, validTypes);
        createDir(fileTypeDirName);
        saveFile(multipartFile);
        return generateResult(multipartFile, fileTypeDirName);
    }

    private void checkFile(MultipartFile multipartFile, long maxSize, List<String> validTypes) {
        if (multipartFile == null || multipartFile.isEmpty()) {
            throw new ServiceException(ServiceCode.ERROR_UPLOAD_EMPTY, "上传失败,请选择你要上传的文件");
        }

        if (multipartFile.getSize() > maxSize * 1024 * 1024) {
            throw new ServiceException(ServiceCode.ERROR_UPLOAD_EXCEED_MAX_SIZE, "上传失败,文件大小不得超过" + maxSize + "MB");
        }

        if (!validTypes.contains(multipartFile.getContentType())) {
            throw new ServiceException(ServiceCode.ERROR_UPLOAD_INVALID_TYPE, "上传失败，仅允许上传以下类型的文件：" + validTypes);
        }
    }

    private void createDir(String fileTypeDirName) {
        File uploadBaseDir = new File(uploadRootDirName, baseDirName);
        File articleImageDir = new File(uploadBaseDir, fileTypeDirName);
        dateDirName = simpleDateFormat.format(new Date());
        uploadDir = new File(articleImageDir, dateDirName);
        if (!uploadDir.exists()) {
            if (!uploadDir.mkdirs()) {
                throw new ServiceException(ServiceCode.ERROR_UNKNOWN, "服务器忙,请稍后再试");
            }
        }

    }

    private void saveFile(MultipartFile multipartFile) throws IOException {
        String newFileName = UUID.randomUUID().toString();
        String originalFilename = multipartFile.getOriginalFilename();
        assert originalFilename != null;
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        fullFileName = newFileName + suffix;
        File newFile = new File(uploadDir, fullFileName);

        multipartFile.transferTo(newFile);
    }

    private UploadResult generateResult(MultipartFile multipartFile, String fileTypeDirName) {
        String url = host + baseDirName + fileTypeDirName + dateDirName + fullFileName;
        UploadResult uploadResult = new UploadResult();
        uploadResult.setUrl(url);
        uploadResult.setFileSize(multipartFile.getSize());
        uploadResult.setContentType(multipartFile.getContentType());
        uploadResult.setFileName(fullFileName);
        return uploadResult;
    }
}
